#coding=utf8
__author__ = 'alex'

import requests
import base64
import json
import logging as log

API_BASE = "http://10.1.1.6:8774"

KEYSTONE_URL = "http://10.1.1.4:5000"
KEYSTONE_URL2 = "http://10.1.1.4:35357"


def fetch(url, data, headers, method):
    try:
        print headers
        print data
        print method
        if data==None:
            r=method(url,headers=headers)
        else:
            r=method(url,data=json.dumps(data),headers=headers)
        if r.status_code in [200,201,202,203]:
            return r.json
        log.error("\n-----------------error---------------\naccess %s with error code %s\n%s"%(url,r.status_code,data))
    except Exception,e:
        log.error(e.message)




class Token(object):
    """
    抽象token概念的类，用于解析token内容
    """
    def __init__(self, osuser, ospassword, ostenant):
        self.token=get_token(osuser, ospassword, ostenant)
        self.valid=True if self.token else False
        self.id=self.token['access']['token']['id']

    def __getitem__(self, item):
        for catalog in self.token['access']['serviceCatalog']:
            if catalog['name']==item:
                return catalog['endpoints'][0]['adminURL']
        return ""

def get_token(osuser, ospassword, ostenant):
    """
    登陆keystone获取登陆token
    :param osuser: 用户名
    :param ospassword:密码
    :param ostenant: 租户
    :return:返回登陆token
    """
    url=KEYSTONE_URL+"/v2.0/tokens"
    body={"auth":{"passwordCredentials": {"username": osuser, "password": ospassword}, "tenantName":ostenant}}
    result = fetch(url, body, {"Content-type":"application/json"}, requests.post)
    if result:
        return result


class TenantUserAcc(object):
    """
    租户和用户关系访问类
    """
    def __init__(self, token, user_id, tenant_id, role_id):
        """
        初始化访问对象
        """
        self.token = token
        self.url = "%s/v2.0/tenants/%s/users/%s/roles/OS-KSADM/%s"%(KEYSTONE_URL2,tenant_id,user_id,role_id)

    def process(self, method):
        return fetch(self.url,{},{"X-Auth-Token":self.token.id, "Content-type":"application/json" },method)

    def put(self):
        return self.process(requests.put)

    def delete(self):
        return self.process(requests.delete)

class APIAcc(object):
    def __init__(self, token ,tenant_id):
        self.token = token
        self.tenant_id = tenant_id
        self.headers={"X-Auth-Token":self.token.id, "Content-type":"application/json" }

    def _process(self, path, method, endpoint='nova'):
        if endpoint:
            px=self.token[endpoint]
        else:
            px=KEYSTONE_URL
        url="%s%s"%(px,path)
        return fetch(url,None, self.headers, method)


    def server_list(self):
        """
        获取服务器列表
        :return:
        """
        path="/servers"
        return self._process(path,requests.get)

    def all_server_details(self):
        """
        获取所有服务器详细信息列表
        :return:
        """
        path="/v2/%s/servers/detail"%self.tenant_id
        return self._process(path,requests.get)

    def flaver_list(self):
        """
        获取所有flavor的列表
        :return:
        """
        path="/flavors"
        return self._process(path,requests.get)

    def image_list(self):
        """
        获取所有镜像的列表
        :return:
        """
        path="/images"
        return self._process(path,requests.get)

    def security_group_list(self):
        """
        获取所有安全组列表
        :return:
        """
        path="/v2/%s/os-security-groups"%self.tenant_id
        return self._process(path,requests.get)

    def host_list(self):
        """
        获取所有host列表
        TODO:这个暂时不用
        :return:
        """
        path="/v2/%s/os-host"%self.tenant_id
        return self._process(path,requests.get)

    def user_list(self):
        """
        获取所有用户
        :return:
        """
        return self._process("/v2.0/users",requests.get)

    def tenant_user_list(self):
        """
        获取租户下用户列表
        :return:
        """
        path="/v2.0/tenants/%s/users"%self.tenant_id
        return self._process(path,requests.get)

    def tenanr_list(self):
        """
        获取所有租户列表
        :return:
        """
        return self._process("/v2.0/tenants",requests.get,endpoint="")

    def role_list(self):
        """
        获取所有role列表
        :return:
        """
        return self._process("/v2.0/OS-KSADM/roles",requests.get)

class Server(object):
    def __init__(self, token , tenant_id, server_id):
        self.token = token
        self.tenant_id =  tenant_id
        self.server_id = server_id
        self.resource_uri="/v2/%s/servers/%s"%(tenant_id,server_id)

    def _process(self, path, data, method,endpoint="nova"):
        url="%s%s"%(self.token[endpoint] if endpoint else KEYSTONE_URL, path)
        return fetch(url, data, {"X-Auth-Token":self.token.id, "Content-type":"application/json" }, method)


    def details(self):
        """
        获取服务器详细信息
        :return:
        """
        return self._process(self.resource_uri,{},requests.get)

    def delete(self):
        """
        删除服务器
        :return:
        """
        return self._process(self.resource_uri,{},requests.delete)

    def suspend(self):
        """
        挂起服务器
        :return:
        """
        path = "/v2/%s/servers/%s/action"%(self.tenant_id,self.server_id)
        body = {'reboot':{'type':'HARD'}}
        return self._process(path,body,requests.post)

    def create(self, server_name, meta_server_name, image_id, flavor_id, security_group, publickey, personalitypath, personalitycontents):
        """
        创建虚拟机
        :param server_name:
        :param meta_server_name:
        :param image_id:
        :param flavor_id:
        :param security_group:
        :param publickey:
        :param personalitypath:
        :param personalitycontents:
        :return:
        """
        path = "/servers"
        spersonality = [ { "path":personalitypath, "contents":base64.b64encode( personalitycontents ) } ]
        restbody={
            "server": {
                "name": server_name,
                "imageRef": image_id,
                "flavorRef": flavor_id,
                "metadata":
                    {
                        "Server Name": meta_server_name
                    },
                "security_groups":security_group,
                "key_name": publickey,
                "personality": spersonality
            }
        }
        return self._process(path,restbody,requests.post)

class User(object):
    def __init__(self, token, user_id=None):
        self.token = token
        self.user_id = user_id

    def _process(self, path, data, method):
        url="%s%s"%(KEYSTONE_URL2, path)
        return fetch(url, data , {"X-Auth-Token":self.token.id, "Content-type":"application/json" }, method)


    def create(self, username, password, email, tenantid=None, enabled=True):
        """
        创建用户
        :param username:
        :param password:
        :param email:
        :param tenantid:
        :param enabled:
        :return:
        """
        if self.user_id:
            return
        path = "/v2.0/users"
        restbody = {"user": {"name": username,
                             "password": password,
                             "email": email,
                             "enabled": enabled}}
        if tenantid:
            restbody['user'][tenantId]=tenantid
        return self._process(path,restbody,requests.post)

    def delete(self):
        """
        删除用户
        :return:
        """
        if self.user_id:
            path = "/v2.0/users/%s"%self.user_id
            return self._process(path,{},requests.delete)

    def update_email(self, new_email):
        """
        更新用户的email
        :param new_email:
        :return:
        """
        if self.user_id:
            path = "/v2.0/users/%s"%self.user_id
            restbody = {'user':{'id':self.user_id},'email':new_email}
            return self._process(path,restbody,requests.post)

    def update_password(self, new_password):
        """
        更新用户的密码
        :param new_password:
        :return:
        """
        if self.user_id:
            path = "/v2.0/users/%s"%self.user_id
            restbody = {'user':{'id':self.user_id},'password':new_password}
            return self._process(path,restbody,requests.post)

    def get_user_role_id(self):
        """
        获取用户的roleid
        :return:
        """
        result = self.get_user_role_refs()
        if result:
            return result['roles'][0]['roleId']

    def get_user_role_refs(self):
        """
        获取用户的role对象
        :return:
        """
        if self.user_id:
            path="/v2.0/users/%s/roleRefs"%self.user_id
            return self._process(path,{},requests.get)

class Tenant(object):
    """
    租户对象
    """
    def __init__(self, token, tenant_id = None):
        self.token = token
        self.tenant_id =  tenant_id

    def _process(self, path, data, method):
        url="%s%s"%(KEYSTONE_URL2,path)
        return fetch(url, data, {"X-Auth-Token":self.token.id, "Content-type":"application/json" }, method)

    def create(self, tenant_name, description, enabled=True):
        """
        创建租户
        :param tenant_name:
        :param description:
        :param enabled:
        :return:
        {u'tenants': [{u'description': None,
   u'enabled': True,
   u'id': u'1ba13500b14241c9b5e1f619c4fa3982',
   u'name': u'adminTenant'},
  {u'description': None,
   u'enabled': True,
   u'id': u'60285709bdca4e40ad0c3b5f367b30c1',
   u'name': u'maotaiTenant'},
  {u'description': None,
   u'enabled': True,
   u'id': u'b2f7d68716dc475e87a2dcd4076e13cc',
   u'name': u'aipuTenant'},
  {u'description': None,
   u'enabled': True,
   u'id': u'd232f183cc9f4f619228d743de474112',
   u'name': u'serviceTenant'}],
 u'tenants_links': []}
        """
        if self.tenant_id:
            return
        path = "/v2.0/tenants"
        restbody = {"tenant": {
            "name": tenant_name,
            "description": description,
            "enabled": True}}
        return self._process(path,restbody,requests.put)

    def delete(self):
        """
        删除租户
        :return:
        """
        if not self.tenant_id:
            return
        path = "/v2.0/tenants/%s"%self.tenant_id
        return self._process(path,{},requests.delete)

    def update(self, description=None, enabled=None):
        """
        更新租户状态
        :param description:
        :param enabled:
        :return:
        """
        if not self.tenant_id:
        return
    path = "/v2.0/tenants/%s"%self.tenant_id
    restbody = {"tenant": {'id': self.tenant_id}}
    if description:
        restbody['tenant']['description'] = description
    if enabled != None:
        restbody['tenant']['enabled'] = enabled
    return self._process(path,restbody,requests.post)